package com.adobe.apprise.database
{
	
	import com.adobe.xml.syndication.generic.IFeed;
	import com.adobe.xml.syndication.generic.IItem;
	
	import flash.data.*;
	import flash.errors.SQLError;
	import flash.events.SQLErrorEvent;
	import flash.events.SQLEvent;
	import flash.filesystem.*;

	public class Database
	{
		private var sql:XML;
		private var dbFile:File;
		public var conn:SQLConnection;
		public var aConn:SQLConnection;
				
		public function Database(sql:XML)
		{
			this.sql = sql;
		}
		
		public function initialize(responder:DatabaseResponder):void
		{
			this.dbFile = File.applicationStorageDirectory.resolvePath("apprise1-5.db");	
			this.aConn = new SQLConnection();
			this.aConn.addEventListener(SQLEvent.OPEN,
				function(e:SQLEvent):void
				{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					responder.dispatchEvent(dbe);
				});
				
			this.aConn.addEventListener(SQLErrorEvent.ERROR,
				function(sqle:SQLErrorEvent):void
				{
					trace(sqle.error);
				});
				
			this.aConn.openAsync(dbFile, SQLMode.CREATE);
		}
		
		public function initSynchronousConnection():void
		{
			this.conn = new SQLConnection();
			this.conn.open(this.dbFile, SQLMode.CREATE);
		}		
		
		public function shutdown():void
		{
			if (this.aConn.connected)
			{
				this.aConn.close();
			}
			if (this.conn.connected)
			{
				this.conn.close();
			}
		}

		/* Feeds */

		public function createFeedsTable(responder:DatabaseResponder):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.feeds.create;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function insertFeed(responder:DatabaseResponder, feedUrl:String, feed:IFeed):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.feeds.insert;
            stmt.parameters[":name"] = (feed.metadata.title != null) ? feed.metadata.title : feedUrl;
            stmt.parameters[":description"] = feed.metadata.description;
            stmt.parameters[":icon"] = null;
            stmt.parameters[":feed_url"] = feedUrl;
            stmt.parameters[":site_url"] = feed.metadata.link;
            stmt.parameters[":sort_order"] = -1;
            stmt.parameters[":etag"] = null;
            stmt.parameters[":last_updated"] = new Date();
            stmt.parameters[":parsable"] = 1;
            stmt.parameters[":path"] = "/";
            stmt.parameters[":error_message"] = null;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().lastInsertRowID;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function insertBadFeed(responder:DatabaseResponder, feedUrl:String, errorMessage:String):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.feeds.insert;
            stmt.parameters[":name"] = feedUrl;
            stmt.parameters[":description"] = null;
            stmt.parameters[":icon"] = null;
            stmt.parameters[":feed_url"] = feedUrl;
            stmt.parameters[":site_url"] = null;
            stmt.parameters[":sort_order"] = -1;
            stmt.parameters[":etag"] = null;
            stmt.parameters[":last_updated"] = new Date();
            stmt.parameters[":parsable"] = 0;
            stmt.parameters[":path"] = "/";
            stmt.parameters[":error_message"] = errorMessage;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().lastInsertRowID;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function updateFeed(responder:DatabaseResponder, feedId:Number, feedUrl:String, feed:IFeed):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.feeds.update;
            stmt.parameters[":name"] = (feed.metadata.title != null) ? feed.metadata.title : feedUrl;
            stmt.parameters[":description"] = feed.metadata.description;
            stmt.parameters[":icon"] = null;
            stmt.parameters[":feed_url"] = feedUrl;
            stmt.parameters[":site_url"] = feed.metadata.link;
            stmt.parameters[":sort_order"] = -1;
            stmt.parameters[":etag"] = null;
            stmt.parameters[":last_updated"] = new Date();
            stmt.parameters[":parsable"] = 1;
            stmt.parameters[":path"] = "/";
            stmt.parameters[":error_message"] = null;
            stmt.parameters[":feed_id"] = feedId;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function updateBadFeed(responder:DatabaseResponder, feedId:Number, errorMessage:String):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.feeds.updateError;
            stmt.parameters[":feed_id"] = feedId;
            stmt.parameters[":parsable"] = 1;
            stmt.parameters[":last_updated"] = new Date();
            stmt.parameters[":error_message"] = errorMessage;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function deleteFeedById(responder:DatabaseResponder, feedId:Number):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.feeds.deleteByFeedId;
            stmt.parameters[":feed_id"] = feedId;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function getFeedInfoById(responder:DatabaseResponder, feedId:Number):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.feeds.selectInfoById;
            stmt.parameters[":feed_id"] = feedId;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
            		var results:SQLResult = stmt.getResult();
					dbe.data = results.data[0];
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function getFeedIdByFeedUrl(responder:DatabaseResponder, feedUrl:String):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.feeds.selectIdByFeedUrl;
            stmt.parameters[":feed_url"] = feedUrl;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
            		var results:SQLResult = stmt.getResult();
					dbe.data = (results.data == null) ? -1 : results.data[0].id;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}
		
		public function getFeeds(responder:DatabaseResponder):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.feeds.selectAll;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().data;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function getFeedUrls(responder:DatabaseResponder):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.feeds.selectUrls;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().data;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function getUnreadFeeds(responder:DatabaseResponder):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.feeds.selectOnlyUnread;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().data;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}
		
		public function getFeedErrorMessageById(responder:DatabaseResponder, feedId:Number):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.feeds.selectErrorMessageById;
            stmt.parameters[":feed_id"] = feedId;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
            		var results:SQLResult = stmt.getResult();
					dbe.data = results.data[0].error_message;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}


		/* Posts */

		public function createPostsTable(responder:DatabaseResponder):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.posts.create;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function getPostByUrl(responder:DatabaseResponder, postUrl:String):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.posts.selectByUrl;
            stmt.parameters[":post_url"] = postUrl;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
            		var results:SQLResult = stmt.getResult();
					dbe.data = (results.data == null) ? null : results.data[0];
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}
		
		public function getPostByTitle(responder:DatabaseResponder, postTitle:String):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.posts.selectByTitle;
            stmt.parameters[":post_title"] = postTitle;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
            		var results:SQLResult = stmt.getResult();
					dbe.data = (results.data == null) ? null : results.data[0];
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function getPostByGuid(responder:DatabaseResponder, id:String):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
			stmt.text = this.sql.posts.selectByGuid;
			stmt.parameters[":guid"] = id;
			stmt.addEventListener(SQLEvent.RESULT,
				function(e:SQLEvent):void
				{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					var results:SQLResult = stmt.getResult();
					dbe.data = (results.data == null) ? null : results.data[0];
					responder.dispatchEvent(dbe); 
				});
			stmt.execute();
		}

		public function insertPost(responder:DatabaseResponder, feedId:Number, item:IItem):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
    		stmt.text = this.sql.posts.insert;
    		stmt.parameters[":guid"] = item.id;
			stmt.parameters[":feed_id"] = feedId;
            stmt.parameters[":title"] = (item.title != null) ? item.title : "(No title)";
            stmt.parameters[":content"] = item.excerpt.value;
            stmt.parameters[":url"] = item.link;
            var postDate:Date;
            try
            {
            	postDate = item.date;
            }
            catch (e:Error)
            {
            	// TBD: The feed is invalid.  Default to today's date, but Flag it.
            	postDate = new Date();
            }
            stmt.parameters[":post_date"] = (postDate != null) ? postDate : new Date();
            stmt.parameters[":read"] = 0;
            stmt.parameters[":checked"] = 0;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().lastInsertRowID;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function updatePost(responder:DatabaseResponder, oldItem:Object, item:IItem):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
    		stmt.text = this.sql.posts.update;
            stmt.parameters[":title"] = (item.title != null) ? item.title : "(No title)";
            stmt.parameters[":content"] = item.excerpt.value;
            stmt.parameters[":url"] = item.link;
            stmt.parameters[":post_date"] = oldItem.post_date;
            stmt.parameters[":read"] = oldItem.read;
            stmt.parameters[":checked"] = oldItem.checked;
            stmt.parameters[":post_id"] = oldItem.id;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function searchPosts(responder:DatabaseResponder, searchTerm:String):void
		{
			if (!this.conn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.conn;
            stmt.text = "SELECT posts.id, feed_id, feeds.name AS feed_name, title, posts.url, post_date, read," + 
            		" checked FROM posts, feeds WHERE " + searchTerm + " AND posts.feed_id = feeds.id ORDER BY posts.post_date DESC;";
						
			try 
			{
            	stmt.execute();
            	var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
				dbe.data = stmt.getResult().data;
				responder.dispatchEvent(dbe);
   			}
   			catch (sqle:SQLError)
   			{
   				//lock problem. not a big problem
   				trace (sqle.errorID);
   			}   			           
		}

		public function getUnreadPosts(responder:DatabaseResponder):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.posts.selectUnread;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().data;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function getCheckedPosts(responder:DatabaseResponder):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.posts.selectChecked;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().data;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function getPostsByFeedId(responder:DatabaseResponder, feedId:Number):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.posts.selectByFeed;
            stmt.parameters[":feed_id"] = feedId;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().data;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function getPostsByAuthor(responder:DatabaseResponder, author:String):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.posts.selectByAuthor;
            stmt.parameters[":author"] = author;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().data;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function getPostsByTopic(responder:DatabaseResponder, topic:String):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.posts.selectByTopic;
            stmt.parameters[":topic"] = topic;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().data;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function updatePostReadFlag(responder:DatabaseResponder, postId:Number, read:Boolean):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
    		stmt.text = this.sql.posts.updateRead;
            stmt.parameters[":post_id"] = postId;
            stmt.parameters[":read"] = read;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function updatePostCheckedFlag(responder:DatabaseResponder, postId:Number, checked:Boolean):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
    		stmt.text = this.sql.posts.updateChecked;
            stmt.parameters[":post_id"] = postId;
            stmt.parameters[":checked"] = checked;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function getPostContentById(responder:DatabaseResponder, postId:Number):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
			stmt.addEventListener(SQLEvent.RESULT,
				function(e:SQLEvent):void
				{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					var data:Array = stmt.getResult().data;
					dbe.data = (data == null || data.length == 0) ? null : data[0].content;
					responder.dispatchEvent(dbe);
				});
			stmt.text = sql.posts.selectContentById;
            stmt.parameters[":post_id"] = postId;
			stmt.execute();
		}

		public function deletePostsByFeedId(responder:DatabaseResponder, feedId:Number):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.posts.deleteByFeedId;
            stmt.parameters[":feed_id"] = feedId;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}


		/* Authors */

		public function createAuthorsTable(responder:DatabaseResponder):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.authors.create;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}
		
		public function deleteAuthorsByPostId(responder:DatabaseResponder, postId:Number):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.authors.deleteByPostId;
            stmt.parameters[":post_id"] = postId;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					responder.dispatchEvent(dbe);
            	});
			stmt.execute();
		}

		public function deleteAuthorsByFeedId(responder:DatabaseResponder, feedId:Number):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.authors.deleteByFeedId;
            stmt.parameters[":feed_id"] = feedId;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function insertAuthor(responder:DatabaseResponder, postId:Number, author:String):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.authors.insert;
            stmt.parameters[":post_id"] = postId;
            stmt.parameters[":author"] = author;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().lastInsertRowID;
					responder.dispatchEvent(dbe);
            	});
			stmt.execute();
		}

		public function getAuthors(responder:DatabaseResponder):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.authors.selectDistinct;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().data;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function getUnreadAuthors(responder:DatabaseResponder):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.authors.selectOnlyUnread;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().data;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}
		
		
		/* Topics */

		public function createTopicsTable(responder:DatabaseResponder):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.topics.create;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function deleteTopicsByPostId(responder:DatabaseResponder, postId:Number):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.topics.deleteByPostId;
            stmt.parameters[":post_id"] = postId;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					responder.dispatchEvent(dbe);
            	});
			stmt.execute();
		}

		public function deleteTopicsByFeedId(responder:DatabaseResponder, feedId:Number):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.topics.deleteByFeedId;
            stmt.parameters[":feed_id"] = feedId;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function insertTopic(responder:DatabaseResponder, postId:Number, topic:String):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.topics.insert;
            stmt.parameters[":post_id"] = postId;
            stmt.parameters[":topic"] = topic;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().lastInsertRowID;
					responder.dispatchEvent(dbe);
            	});
			stmt.execute();
		}

		public function getTopics(responder:DatabaseResponder):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.topics.selectDistinct;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().data;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function getUnreadTopics(responder:DatabaseResponder):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.topics.selectOnlyUnread;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = stmt.getResult().data;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}
		
		
		/* Counts */

		public function getUnreadCount(responder:DatabaseResponder):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.posts.countUnread;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
            		var count:Number = stmt.getResult().data[0].unread as Number;
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = count;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}

		public function getCheckedCount(responder:DatabaseResponder):void
		{
			if (!this.aConn.connected) return;
			var stmt:SQLStatement = new SQLStatement();
			stmt.sqlConnection = this.aConn;
            stmt.text = this.sql.posts.countChecked;
            stmt.addEventListener(SQLEvent.RESULT,
            	function(e:SQLEvent):void
            	{
            		var count:Number = stmt.getResult().data[0].checked as Number;
					var dbe:DatabaseEvent = new DatabaseEvent(DatabaseEvent.RESULT_EVENT);
					dbe.data = count;
					responder.dispatchEvent(dbe);
            	});
            stmt.execute();
		}
	}
}